import { Skeleton, Card, Image, Button, Footer } from "antd-mobile";
import { Link } from "react-router-dom";
import { Lessons } from "@/store/slices/home";
import React, { useReducer, forwardRef, useEffect } from "react";
interface HomeLessonsProps {
  lessons: Lessons;
  fetchMoreLessons: () => void;
  // 虚拟列表 5. 记录  HomeLessons 父级容器的ref
  contentRef: React.RefObject<HTMLDivElement>;
}
const SWIPE_HEIGHT = 160; //  虚拟列表 6. 轮播图高度
const ITEM_HEIGHT = 300; // 虚拟列表 7. 每个课程卡片的高度

// 虚拟列表 8. 不同机型的缩放
function getScale() {
  const remSize = parseFloat(document.documentElement.style.fontSize);
  // 稿子 是 以 20 为基础
  return remSize / 20;
}
const HomeLessons = forwardRef<() => void, HomeLessonsProps>(
  ({ lessons, fetchMoreLessons, contentRef }, ref) => {
    const [, forceUpdate] = useReducer((x) => x + 1, 0);
    // 虚拟列表 9. 给父级虚拟列表赋予强制更新函数
    useEffect(() => {
      (ref as React.MutableRefObject<() => void>).current = forceUpdate;
    }, []);
    // 虚拟列表 10. 获取不同机型的缩放
    const scale = getScale();
    // 虚拟列表 11. 每条数据的高度
    const realItemHeight = ITEM_HEIGHT * scale;
    // 虚拟列表 12.  容器的高度 = 可见屏幕 - (底部 bar + nav top )  轮播图包含在里面
    const containerHeight = window.innerHeight - 100 * scale;
    // 虚拟列表 13. 定义开始索引 和 结束索引
    let start = 0,
      end = 0;
    // 虚拟列表 14. 获取父级容器的DOM引用
    const content = contentRef.current;
    // 虚拟列表 15. 获取容器的向上卷去的高度 向上卷去的高度要减去轮播图的高度才是课程列表正向向上卷去的高度
    const scrollTop = content
      ? Math.max(content!.scrollTop - SWIPE_HEIGHT * scale, 0)
      : 0;
    // 虚拟列表 16. 向上卷去的高度除以每个条目的高度向下取整就是起始索引
    start = Math.floor(scrollTop! / realItemHeight);
    // 虚拟列表 17. 起始索引加上一页的条目数量就是结束索引. 每页的条目数量等于容器的高度除以每个条目的高度
    end = start + Math.floor(containerHeight / realItemHeight);
    // 虚拟列表 18. 起始索引向上多个二条，避免白屏
    start = Math.max(start - 2, 0);
    // 虚拟列表 19. 结束索引向下多取2条，避免白屏
    end = Math.min(end + 2, lessons.list.length);
    // 虚拟列表 20. 截取出真正要渲染的课程数组 出现在屏幕的数据，去渲染
    const visibleList = lessons.list
      .map((item, index) => ({ ...item, index }))
      .slice(start, end);
    // 虚拟列表 21. 每条数据 的 样式
    const itemStyle = {
      position: "absolute" as const,
      left: 0,
      width: "100%",
      height: realItemHeight,
    };
    // 虚拟列表 22. 课表总长度
    const contentHeight = lessons.list.length * realItemHeight + "px";
    return (
      <section>
        {visibleList.length > 0 ? (
          // 虚拟列表 23. 课表总容器
          <div
            style={{
              position: "relative",
              width: "100%",
              height: contentHeight,
            }}
          >
            {/*  虚拟列表 24. 可见数据渲染 */}
            {visibleList.map((lesson) => (
              <Link
                style={{
                  ...itemStyle,
                  top: `${lesson.index * realItemHeight}px`,
                }}
                key={lesson.id}
                to={{ pathname: `/detail/${lesson.id}` }}
                state={lesson}
              >
                <Card
                  headerStyle={{ display: "flex", justifyContent: "center" }}
                  title={lesson.title}
                >
                  <Image src={lesson.poster} />
                </Card>
              </Link>
            ))}
          </div>
        ) : (
          <Skeleton.Title animated />
        )}
        {lessons.hasMore ? (
          <Button
            onClick={fetchMoreLessons}
            disabled={lessons.loading}
            loading={lessons.loading}
            block
          >
            {lessons.loading ? "" : "加载更多"}
          </Button>
        ) : (
          <Footer label="后面没有了"></Footer>
        )}
      </section>
    );
  }
);
export default HomeLessons;
